package com.zhongli.devplatform.security.weixin;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhongli.devplatform.bean.SecurityUser;
import com.zhongli.devplatform.mapper.sys.ReadRoleMapper;
import com.zhongli.devplatform.mapper.user.ReadUserMapper;
import com.zhongli.devplatform.po.user.ReadRolePO;
import com.zhongli.devplatform.po.user.ReadUserPO;
import com.zhongli.devplatform.utils.BeanCopierUtil;
import com.zhongli.devplatform.vo.user.UserVO;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.util.ArrayList;
import java.util.List;

public class WeixinAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private ReadUserMapper accountMapper;

    @Autowired
    private ReadRoleMapper roleMapper;


    @SneakyThrows
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        WeixinAuthenticationToken WeixinAuthenticationToken = (com.zhongli.devplatform.security.weixin.WeixinAuthenticationToken) authentication;
        String openId = WeixinAuthenticationToken.getWeixinId();
        ReadUserPO accountPO = accountMapper.selectOne(new QueryWrapper<ReadUserPO>().eq("weixin_id", openId));
        if (accountPO == null) {
            return null;
        }
        UserVO userVO = BeanCopierUtil.copy(accountPO, UserVO.class);

        assert userVO != null;
        List<ReadRolePO> rolePOList = roleMapper.selectList(new QueryWrapper<ReadRolePO>().inSql("id",
                "select role_id from read_user_role where user_id =" + userVO.getId()));

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (ReadRolePO rolePO : rolePOList) {
            grantedAuthorities.add(new SimpleGrantedAuthority(rolePO.getCode()));
        }

        SecurityUser securityUser = new SecurityUser(userVO.getAccountNum(), userVO.getPassword(), grantedAuthorities);
        return new WeixinAuthenticationToken(openId, securityUser);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (WeixinAuthenticationToken.class
                .isAssignableFrom(authentication));
    }
}
